#include "DHT.h"
#include "Delay.h"

// 初始化为输出模式
void DHT_Init_Output(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

// 初始化为输入模式
void DHT_Init_Input(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

// 进入读取状态初始化
int Status_Init(void)
{
    DHT_Init_Output();
    dht_low;
    Delay_ms(18); // 拉低至少 18ms
    dht_high;
    Delay_us(30); // 拉高 20-40us
    DHT_Init_Input();
    Delay_us(40); // 等待 DHT11 响应
    if (dht_read == 0)
    {
        while (dht_read == 0); // 等待低电平结束
        while (dht_read == 1); // 等待高电平结束
        return 1; // 初始化成功
    }
    return 0; // 初始化失败
}

// 读取每一个字节（8 bit）
char ReadByte(void)
{
    char out = 0;
    for (int i = 0; i < 8; i++)
    {
        while (dht_read == 0); // 等待低电平结束
        Delay_us(40); // 延时 40 微秒
         out <<= 1; // 左移一位并将最低位设置为 0
        if (dht_read == 1)
        {
            out |= 1; // 左移一位并将最低位设置为 1
        }
       
        while (dht_read == 1); // 等待高电平结束
    }
    return out;
}

// 读取DHT11的数据
int ReadDht11Data(unsigned char *buf)
{
    uint8_t r1, r2, r3, r4, r5;
    if (Status_Init() == 0)
    {
        return 0; // 初始化失败
    }
    r1 = ReadByte();
    r2 = ReadByte();
    r3 = ReadByte();
    r4 = ReadByte();
    r5 = ReadByte();
    dht_low; // 当最后一bit数据传送完毕后，DHT11拉低总线 50us
    Delay_us(55); // 延时 55us
    dht_high; // 随后总线由上拉电阻拉高进入空闲状态
    if (r1 + r2 + r3 + r4 == r5) // 校验和
    {
        buf[0] = r1;
        buf[1] = r2;
        buf[2] = r3;
        buf[3] = r4;
        buf[4] = r5;
        return 1; // 读取成功
    }
    return 0; // 校验失败
}